package com.zbkj.crmeb.order.pprocess;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import com.zbkj.crmeb.chant.request.PurchaseProductRequest;
import com.zbkj.crmeb.enums.RoleEnum;
import com.zbkj.crmeb.merchant.api.request.BuyMemberRequest;
import com.zbkj.crmeb.payment.service.OrderPayService;
import com.zbkj.crmeb.store.model.StoreOrderInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.constants.Constants;
import com.constants.WeChatConstants;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.util.StringUtil;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.utils.HttpUtils;
import com.zbkj.crmeb.finance.model.UserRecharge;
import com.zbkj.crmeb.finance.service.UserRechargeService;
import com.zbkj.crmeb.front.request.OrderCreateRequest;
import com.zbkj.crmeb.front.response.OrderPayItemResponse;
import com.zbkj.crmeb.front.response.OrderPayResponse;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.request.StoreOrderRefundRequest;
import com.zbkj.crmeb.system.model.SystemAdmin;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemConfigService;

/**
 * @ClassName: wechatOrderProcess
 * @Description: 微信支付方式
 */
@Service("wechatOrderProcess")
public class WechatOrderProcess extends AbstractOrangePayOrderProcess {
    public Logger logger = LoggerFactory.getLogger(this.getClass());
    @Value("${orange.appId}")
    private String appId;
    @Value("${orange.secret}")
    private String secret;
    @Value("${orange.url}")
    private String url;
    private static final Integer CONNECT_TIME_OUT = 5000;
    private static final Integer RESP_TIME_OUT = 30000;

    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserRechargeService userRechargeService;
    @Autowired
    private SystemAdminService systemAdminService;

    public OrderPayResponse creatPayOrder(String key, OrderCreateRequest orderRequest, String ip) {
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        StoreOrder storeOrder = super.createOrder(key, orderRequest, ip);
        orderPayResponse.setStatus("WECHAT_PAY");
        orderPayResponse.addExtend("orderId",storeOrder.getOrderId());
        // 检查订单状态
        OrderPayItemResponse itemResponse = getResponese(storeOrder);
        orderPayResponse.setResult(itemResponse);
        return orderPayResponse;
    }

    @Override
    public HashMap<String, Object> toPayOrder(StoreOrder order, String ip) {
    	HashMap<String, Object> resultMap = new HashMap<>();
    	resultMap.put("result", "SUCCESS");
    	resultMap.put("status", "WECHAT_Chengzi_PAY");
    	resultMap.put("data", getResponese(order));
    	return resultMap;
    }

    @Override
    public boolean refund(StoreOrderRefundRequest request, StoreOrder storeOrder, StoreOrderInfo storeOrderInfo) {
        if(null == request.getAmount() || request.getAmount().compareTo(BigDecimal.ZERO)==0){
            return goOnRefund(request, storeOrder,storeOrderInfo);
        }
        Map<String, Object> map = getParam(storeOrder, request.getAmount());
        String sign = getSign(storeOrder, request.getAmount());
        logger.info("请求橙子退款参数,param:{} ------- sign:{}", JSONObject.toJSONString(map), sign);
        try {
            String result = HttpUtils.post(url, CrmebUtil.mapToStringUrl(map), RESP_TIME_OUT, CONNECT_TIME_OUT, sign);
            logger.info("请求橙子退款返回,result:{}", JSONObject.toJSONString(result));
            if (null != result) {
                Map orangeMap = JSONObject.parseObject(result, Map.class);
                if ("SUCCESS".equals(orangeMap.get("code"))) {
                    return goOnRefund(request, storeOrder,storeOrderInfo);
                }else {
                    storeOrderStatusService.saveRefund(storeOrderInfo.getOrderId(),storeOrderInfo.getChildOrderNumber(), request.getAmount(), "失败,错误信息:"+ orangeMap.get("code"),request.getType() == 1);
                    throw new CrmebException(orangeMap.get("code") + "");
                }
            }
        } catch (Exception e) {
            logger.info("请求橙子退款失败e", e);
        }
        return false;
    }

    @Override
    public Object buyMember(BuyMemberRequest request) {
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("result", "SUCCESS");
        resultMap.put("status", "WECHAT_Chengzi_PAY");
        resultMap.put("data", getMemberResponse(request));
        return resultMap;
    }

    @Override
    public Map<String, Object> purchaseProduct(PurchaseProductRequest purchaseProductRequest, String ip) {
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("result", "SUCCESS");
        resultMap.put("status", "WECHAT_Chengzi_PAY");
        resultMap.put("data", getPurchaseResponse(purchaseProductRequest));
        return resultMap;
    }

    private OrderPayItemResponse getPurchaseResponse(PurchaseProductRequest purchaseProductRequest) {
        OrderPayItemResponse itemResponse = new OrderPayItemResponse();
        // 获取域名
        String domain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
        itemResponse.setKey(purchaseProductRequest.getOrderNo());
        itemResponse.setOrderId(purchaseProductRequest.getOrderNo());
        itemResponse.setAppId(appId);
        itemResponse.setNotifyUrl(domain + WeChatConstants.PAY_NOTIFY_MEMBER_API_URI_ORANGE);
        itemResponse.setAmount(RoleEnum.getEnumByCode(purchaseProductRequest.getProductType()).getPrice());
        itemResponse.setOrderDesc(StrUtil.format("购买服务：{}", RoleEnum.getEnumByCode(purchaseProductRequest.getProductType()).getMsg()));
        itemResponse.setV("1.0");
        itemResponse.setT(System.currentTimeMillis());
        return itemResponse;
    }

    private OrderPayItemResponse getMemberResponse(BuyMemberRequest request) {
        OrderPayItemResponse itemResponse = new OrderPayItemResponse();
        //获取域名
        String domain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
        itemResponse.setKey(request.getOrderNo());
        itemResponse.setOrderId(request.getOrderNo());
        itemResponse.setAppId(appId);
        itemResponse.setNotifyUrl(domain + WeChatConstants.PAY_NOTIFY_MEMBER_API_URI_ORANGE);
        itemResponse.setAmount(request.getPrice());
        itemResponse.setOrderDesc("购买会员");
        itemResponse.setV("1.0");
        itemResponse.setT(System.currentTimeMillis());
        return itemResponse;
    }

    private OrderPayItemResponse getResponese(StoreOrder order) {
        OrderPayItemResponse itemResponse = new OrderPayItemResponse();
        //获取域名
        String domain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
        itemResponse.setKey(order.getOrderId());
        itemResponse.setOrderId(order.getOrderId());
        itemResponse.setAppId(appId);
        itemResponse.setNotifyUrl(domain + WeChatConstants.PAY_NOTIFY_API_URI_ORANGEPAY);
        itemResponse.setAmount(order.getPayPrice());
        itemResponse.setOrderDesc("购买商品");
        itemResponse.setV("1.0");
        itemResponse.setT(System.currentTimeMillis());
        return itemResponse;
    }

    private String getSign(StoreOrder order, BigDecimal amount) {
        Map<String, Object> map = getParam(order, amount);
        String sign = CrmebUtil.getOrangeSign(map, secret);
        return sign;
    }

    private Map<String, Object> getParam(StoreOrder order, BigDecimal amount) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("amount", String.valueOf(amount));
        map.put("api", "order.refundOrder");
        map.put("appId", appId);
        map.put("v", "1.0");

        map.put("t", DateUtil.longToDate(System.currentTimeMillis(), Constants.DATE_TIME_FORMAT_NUM));
        map.put("serialNumber", "tk-" + order.getOrderId()+DateUtil.longToDate(System.currentTimeMillis(), Constants.DATE_TIME_FORMAT_NUM));
        map.put("userOrderNum", order.getOrderId());
        return map;
    }

    @Override
    public UserRecharge createImgRecharge(BigDecimal price) {
        String orderId = CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT);
        
        // 创建橙子二维码订单
        String domain = systemConfigService.getValueByKeyException(Constants.CONFIG_KEY_API_URL);
        HashMap<String, Object> map = new HashMap<>();
        map.put("amount", price);
        map.put("api", "order.createOrder");
        map.put("appId", appId);
        map.put("notifyUrl", domain + WeChatConstants.PAY_NOTIFY_API_URI_ORANGEPAY);
        map.put("v", "1.0");
        map.put("t", DateUtil.longToDate(System.currentTimeMillis(), Constants.DATE_TIME_FORMAT_NUM));
        map.put("payModeNo", "WeixinScan");
        map.put("userOrderNum", orderId);
        String sign = CrmebUtil.getOrangeSign(map, secret);

        logger.info("--------------- 请求橙子二维码订单参数,param:{}, ------- sign:{}---------------", JSONObject.toJSONString(map), sign);
        try {
            String result = HttpUtils.post(url, CrmebUtil.mapToStringUrl(map), RESP_TIME_OUT, CONNECT_TIME_OUT, sign);
            logger.info("请求橙子二维码订单返回, result: {}", JSONObject.toJSONString(result));
            if (StringUtil.isNotEmpty(result)) {
                JSONObject resultObj = JSONObject.parseObject(result);
                if ("SUCCESS".equals(resultObj.getString("code"))) {
                    JSONObject dataJson = resultObj.getJSONObject("data");
                    String payImage = dataJson.getString("tradeQrCodeImg");
                    String orderNum = dataJson.getString("orderNum");
                    
                    // 生成系统订单数据
                    SystemAdmin admin = systemAdminService.getInfo();
                    JSONArray merIds = JSONArray.parseArray(admin.getMerId());
                    UserRecharge userRecharge = new UserRecharge();
                    userRecharge.setMerId(merIds.getInteger(0));
                    userRecharge.setUid(admin.getId());
                    userRecharge.setOrderId(orderId);
                    userRecharge.setPrice(price);
                    userRecharge.setType(true);
                    userRecharge.setStatus(1);
                    userRecharge.setRechargeType(Constants.PAY_TYPE_WE_CHAT_FROM_PROGRAM);
                    userRecharge.setPaid(false);
                    userRecharge.setPayImage(payImage);
                    userRecharge.setOrderNum(orderNum);
                    userRecharge.setCreateTime(new Date());
                    userRecharge.setUpdateTime(new Date());
                    userRechargeService.save(userRecharge);
                    
                    return userRecharge;
                }
            }
        } catch (Exception e) {
            logger.info("请求橙子二维码订单失败", e);
        }
        
        return null;
    }
}
